from jili.ss.ss_base import ss_base
from jili.pos import creat_pos
from jili.data.db import tickload_dataset_byobj,barload_dataset_byobj
from jili.trade.constants import bs
from jili.pos.assets_returns import asset_returns
class ss_cta(ss_base):
    def __init__(self,config):
        super(ss_cta).__init__(config)
        self.obj=self.obj_bar[-1]
        self.pos=None
        self.last_bars={}
        self.asset_return_list=asset_returns()
    def init(self):
        r=True
        if self.ss_mode=="sim":
            brokerid = ""
            investid = ""
            password = ""
            broker_type = "sim"
            if "pos" in self.config.keys():
                posconfig=self.config["pos"]
                if "brokerid" in posconfig.keys():
                    brokerid=posconfig["brokerid"]
                if "investid" in posconfig.keys():
                    investid=posconfig["investid"]
                if "password" in posconfig.keys():
                    password=posconfig["password"]
                if "broker_type" in posconfig.keys():
                    adapter_type=posconfig["broker_type"]
            self.pos = creat_pos(brokerid, investid, password, adapter_type)
        else:
            if "pos" in self.config.keys():
                posconfig=self.config["pos"]
                if "brokerid" in posconfig.keys():
                    brokerid=posconfig["brokerid"]
                else:
                    r= False
                if "investid" in posconfig.keys():
                    investid=posconfig["investid"]
                else:
                    r= False
                if "password" in posconfig.keys():
                    password=posconfig["password"]
                else:
                    r= False
                if "broker_type" in posconfig.keys():
                    adapter_type=posconfig["broker_type"]
                else:
                    r= False
                if r:
                    self.pos=creat_pos(brokerid,investid,password,adapter_type)
            self.sub_bar(self.obj)
        return r
    def getdataset_bytick(self):
        startdate=""
        enddate=""
        tc=self.config.get("backtest",{})
        if tc:
            startdate=tc.get("startdate","")
            enddate=tc.get("enddate","")
        if self.backtest_datafrom=="pkl":
            return tickload_dataset_byobj(self.obj,startdate,enddate)
        elif self.backtest_datafrom=="csv":
            return tickload_dataset_byobj(self.obj,startdate,enddate,"csv")
        else:
            return tickload_dataset_byobj(self.obj, startdate, enddate, "mongo")
    def getdataset_by1mbar(self):
        startdate = ""
        enddate = ""
        tc = self.config.get("backtest", {})
        if tc:
            startdate = tc.get("startdate", "")
            enddate = tc.get("enddate", "")
        if self.backtest_datafrom == "pkl":
            return barload_dataset_byobj(self.obj,startdate,enddate)
        else:
            return barload_dataset_byobj(self.obj,startdate,enddate,"mongo")

    def onbar_app(self,bars):
        obj=bars["obj"]
        timekey=bars["timekey"]
        self.last_bars[obj]=bars
        asset,pl=self.calcasset()
        self.asset_return_list.setdata(timekey=timekey,asset=asset,asset_limit=pl)
        super(ss_cta, self).onbar_app(bars)
    def calcasset(self):
        a=0
        pl=0
        for obj,v in self.poss["byobj"].items():
            for pos in v.values():
                if obj in self.last_bars.keys():
                    price=self.last_bars[obj]["1m"]["close"]
                    asset0=pos.calcpos(price)
                    if pos.bs==bs.buy:
                        p1=self.last_bars[obj]["1m"]["low"]
                    else:
                        p1=self.last_bars[obj]["1m"]["high"]
                    asset1 = pos.calcpos(p1)
                    a=a+asset0
                    pl=pl+asset1
                else:
                    a = a +pos.margin
                    pl=pl+pos.margin
        self.fund.asset=a+self.fund.avlcash+self.frozenfund
        asset1=pl+self.fund.avlcash+self.frozenfund
        return self.fund.asset,asset1
